﻿using System;
using System.Collections.Generic;
using System.Linq;
using GDM.Hogar.Aplicacion.Properties;
using GDM.Hogar.Entidades;
using GDM.Hogar.Entidades.Enums;
using GDM.Hogar.Managers.Contratos;
using GDM.Hogar.Soporte.Helpers;
using GDM.Hogar.Soporte.SafeCast;

namespace GDM.Hogar.Aplicacion.Formularios.ParteDiarioComedor
{
    public partial class FrmParteDiarioComedor
#if DEBUG
 : AdaptadorFrm
#else
     : FrmBase
#endif
    {
        private readonly IPersonalCocinaManager _personalCocinaManager;
        private readonly IParteDiarioComedorManager _parteDiarioComedorManager;

        public ConsultaParteDiarioComedor ParteDiarioComedor { get; set; }

        public Action OnParteComedorCreado;
        public Action OnParteComedorActualizado;

        private readonly TrueOrFalse _seCocino = new TrueOrFalse();

        private bool EsCoordinadorOAdministrativo
        {
            get { return ContextoUsuario.RolId == (int)Rol.Coordinador || ContextoUsuario.RolId == (int)Rol.Administrativo; }
        }

        protected override string Titulo
        {
            get { return "Parte Diario de Comedor"; }
        }

        public FrmParteDiarioComedor(IParteDiarioComedorManager parteDiarioComedorManager, IPersonalCocinaManager personalCocinaManager)
        {
            if (parteDiarioComedorManager == null)
                throw new ArgumentNullException("parteDiarioComedorManager");
            if (personalCocinaManager == null)
                throw new ArgumentNullException("personalCocinaManager");

            _parteDiarioComedorManager = parteDiarioComedorManager;
            _personalCocinaManager = personalCocinaManager;
            InitializeComponent();
        }

        private void CargarPersonalCocina()
        {
            var personalCocina = _personalCocinaManager.ObtenerPersonalCocina();
            cklPersonalCocina.DataSource = personalCocina;
            cklPersonalCocina.DisplayMember = "NombreCompleto";
            cklPersonalCocina.ValueMember = "PersonalCocinaId";
        }

        private void SeleccionarPersonalCocina()
        {
            for (var i = 0; i < cklPersonalCocina.Items.Count; i++)
            {
                var personalCocina = (PersonalCocina)cklPersonalCocina.Items[i];
                if (ParteDiarioComedor.PersonalDeCocinaIds.Contains(personalCocina.PersonalCocinaId))
                {
                    cklPersonalCocina.SetItemChecked(i, true);
                }
            }
        }

        private void MostrarDatosParteDiarioComedor()
        {
            txtMenu.Text = ParteDiarioComedor.Menu;
            txtNroRacionesRealizadas.Text = ParteDiarioComedor.CantidadRealizada.ToString();
            txtRacionesEntregadasComedor.Text = ParteDiarioComedor.CantidadEntregadaComedor.ToString();
            txtRacionesEntregadasViandas.Text = ParteDiarioComedor.CantidadEntregadaVianda.ToString ();
            txtObservaciones.Text = ParteDiarioComedor.Observacion;
            dtpFecha.Value = ParteDiarioComedor.Fecha.Date;
            dtpFecha.Enabled = false;
            if (ParteDiarioComedor.PersonalDeCocinaIds != null && ParteDiarioComedor.PersonalDeCocinaIds.Any())
            {
                SeleccionarPersonalCocina();
            }
        }

        private void SetearHabilitacionDeControles()
        {
            txtNroRacionesRealizadas.DataBindings.Add("Enabled", _seCocino, "IsTrue");
            txtRacionesEntregadasComedor.DataBindings.Add("Enabled", _seCocino, "IsTrue");
            txtRacionesEntregadasViandas.DataBindings.Add("Enabled", _seCocino, "IsTrue");
            txtMenu.DataBindings.Add("Enabled", _seCocino, "IsTrue");
            cklPersonalCocina.DataBindings.Add("Enabled", _seCocino, "IsTrue");
        }

        private void FrmParteDiarioComedor_Load(object sender, EventArgs e)
        {
            SetearHabilitacionDeControles();
            RefrescarCambios = false;
            CargarPersonalCocina();
            dtpFecha.MinDate = FechaHelper.InicioPrimerQuincena(1, DateTime.Now.Year);
            dtpFecha.MaxDate = DateTime.Now.Date;
            if (ParteDiarioComedor == null)
            {
                return;
            }
            MostrarDatosParteDiarioComedor();
            ckbNoCocino.Checked = string.IsNullOrEmpty(txtNroRacionesRealizadas.Text);
            ckbNoCocino.Enabled = false;
            if (!EsCoordinadorOAdministrativo)
            {
                //- El agente debe estar activo para poder editar sus datos
                HabilitarControl(panel1, false);
                btnGuardarParteDiario.Visible = false;
            }
        }

        private void ActualizarParteDiarioComedor()
        {
            var datosParteComedor = InstanciarParteDiarioComedor();
            try
            {
                datosParteComedor.ParteDiarioComedor.ParteDiarioComedorId = ParteDiarioComedor.ParteDiarioComedorId;
                var parteDiaroComedorAsXml = XmlHelper.GetXml(datosParteComedor);
                parteDiaroComedorAsXml = XmlHelper.RemoveAllNamespaces(parteDiaroComedorAsXml);
                _parteDiarioComedorManager.ActualizarParteDiarioComedor(parteDiaroComedorAsXml);
                MostrarMensajeExito(Resources.ParteDiario_GuardoConExito);
                if (OnParteComedorActualizado != null)
                {
                    OnParteComedorActualizado();
                }
            }
            catch (Exception ex)
            {
                MostrarMensajeError(Resources.GuardarParteComedor_Error);
            }
        }

        private DatosParteMensualComedor InstanciarParteDiarioComedor()
        {
             var parteMensualComedor = new ParteMensualComedor
            {
                Mes = dtpFecha.Value.Month,
                Año = DateTime.Now.Year,
            };
            var parteDiarioComedor = new Entidades.ParteDiarioComedor
                {
                    CantidadRealizada = SafeCast.ToInteger(txtNroRacionesRealizadas.Text),
                    CantidadEntregadaComedor = SafeCast.ToInteger(txtRacionesEntregadasComedor.Text),
                    CantidadEntregadaVianda = SafeCast.ToInteger(txtRacionesEntregadasViandas.Text),
                    Fecha = dtpFecha.Value.Date,
                    Menu = txtMenu.Text.Trim(),
                    Observacion = txtObservaciones.Text.Trim()
                };
            var datosParteDiarioComedor = new DatosParteMensualComedor {
                ParteDiarioComedor = parteDiarioComedor, 
                PersonalCocina = new List<PersonalCocina>(),
                ParteMensualComedor = parteMensualComedor
            };
            foreach (var personalCocina in cklPersonalCocina.CheckedItems.Cast<PersonalCocina>())
            {
                datosParteDiarioComedor.PersonalCocina.Add(new PersonalCocina{ PersonalCocinaId = personalCocina.PersonalCocinaId});
            }
            return datosParteDiarioComedor;
        }

        private void CrearParteDiarioComedor()
        {
            var datosParteComedor = InstanciarParteDiarioComedor();
            try
            {
                var parteDiaroComedorAsXml = XmlHelper.GetXml(datosParteComedor);
                parteDiaroComedorAsXml = XmlHelper.RemoveAllNamespaces(parteDiaroComedorAsXml);
                _parteDiarioComedorManager.GuardarParteDiarioComedor(parteDiaroComedorAsXml);
                MostrarMensajeExito(Resources.ParteDiario_GuardoConExito);
                LimpiarControl(panel1);
                foreach (int index in cklPersonalCocina.CheckedIndices)
                {
                    cklPersonalCocina.SetItemChecked(index, false);
                }
                if (OnParteComedorCreado != null)
                {
                    OnParteComedorCreado();
                }
            }
            catch (Exception ex)
            {
                MostrarMensajeError(Resources.GuardarParteComedor_Error);
            }
        }

        private void GuardarRegistro()
        {
            if (!ParteDiarioComedorValidador.Validate()) return;

            if (ParteDiarioComedor != null)
            {
                //- Modo Edicion
                ActualizarParteDiarioComedor();
            }
            else
            {
                //- Modo Creacion
                if (_parteDiarioComedorManager.ExisteParteDiarioComedor(dtpFecha.Value.Date))
                {
                    MostrarMensajeError(string.Format(Resources.ParteDiario_Existe, dtpFecha.Value.ToShortDateString()));
                    return;
                }
                CrearParteDiarioComedor();
            }
        }

        private void btnGuardarParteDiario_Click(object sender, EventArgs e)
        {
            GuardarRegistro();
        }

        private void ParteDiarioComedorValidador_CustomValidation(object sender, Controles.Validador.Componentes.ValidationEventArgs e)
        {
            if (e.Control == dtpFecha)
            {
                e.Valid = !dtpFecha.Value.IsWeekend();
            }
            if (e.Control == cklPersonalCocina)
            {
                e.Valid = cklPersonalCocina.CheckedIndices.Count > 0;
            }
        }

        private void ckbNoCocino_CheckedChanged(object sender, EventArgs e)
        {
            _seCocino.IsTrue = !ckbNoCocino.Checked;
            if (!_seCocino.IsTrue)
            {
                ParteDiarioComedorValidador.SetType(this.txtObservaciones,
                    Controles.Validador.Componentes.ValidationType.Required);
                ParteDiarioComedorValidador.SetRequiredMessage(this.txtObservaciones,
                    "Indique la razon por la cual no se cocino");
            }
            else
            {
                ParteDiarioComedorValidador.SetType(this.txtObservaciones,
                    Controles.Validador.Componentes.ValidationType.None);
                ParteDiarioComedorValidador.SetRequiredMessage(this.txtObservaciones,
                   string.Empty);
            }
        }
    }
}